package com.lt.interactive.wechat.service.impl;

import com.alibaba.fastjson.JSONObject;

import com.lt.bcra.exception.BaseException;
import com.lt.bcra.result.ResponseEnum;
import com.lt.bcra.result.ResultData;


import com.lt.interactive.wechat.entity.BcraPersonalInfo;
import com.lt.interactive.wechat.service.BcraPersonalInfoService;
import com.lt.interactive.wechat.service.WechatService;
import com.lt.interactive.wechat.handler.ConstantWxPropertiesUtils;
import lombok.extern.slf4j.Slf4j;
import lt.bcra.jwt.JwtHelper;
import lt.bcra.utils.EmojiFilter;
import lt.bcra.utils.HttpClientUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class WechatServiceImpl implements WechatService {

    @Autowired
    BcraPersonalInfoService bcraPersonalInfoService;

    @Override
    public ResultData getQrCode() {
        Map<String, Object> map = new HashMap<>();
        map.put("appid", ConstantWxPropertiesUtils.WX_OPEN_APP_ID);
        map.put("redirectUri", ConstantWxPropertiesUtils.WX_OPEN_REDIRECT_URL);
        map.put("scope", "snsapi_login");
        map.put("state", System.currentTimeMillis()+"");//System.currentTimeMillis()+""
        return ResultData.getResult(map);
    }

    @Override
    public void callBack(String code, String state, HttpServletResponse response, HttpServletRequest request) throws IOException {

        if (code==null){
            String url=ConstantWxPropertiesUtils.BCRA_BASE_URL;
            response.sendRedirect(url);
        }

        //第一步 获取临时票据 code
        System.out.println("code:"+code);
        //第二步 拿着code和微信id和秘钥，请求微信固定地址 ，得到两个值
        //使用code和appid以及appscrect换取access_token
        //  %s   占位符
        StringBuffer baseAccessTokenUrl = new StringBuffer()
                .append("https://api.weixin.qq.com/sns/oauth2/access_token")
                .append("?appid=%s")
                .append("&secret=%s")
                .append("&code=%s")
                .append("&grant_type=authorization_code");
        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
                ConstantWxPropertiesUtils.WX_OPEN_APP_ID,
                ConstantWxPropertiesUtils.WX_OPEN_APP_SECRET,
                code);

        //使用httpclient请求这个地址
        try {
            String accesstokenInfo = HttpClientUtils.get(accessTokenUrl);
            System.out.println("accesstokenInfo:"+accesstokenInfo);
            //从返回字符串获取两个值 openid  和  access_token
            JSONObject jsonObject = JSONObject.parseObject(accesstokenInfo);
            String access_token = jsonObject.getString("access_token");
            String openid = jsonObject.getString("openid");

            //判断数据库是否存在微信的扫描人信息
            //根据openid判断
            BcraPersonalInfo bcraPersonalInfo = bcraPersonalInfoService.selectWxInfoOpenId(openid);

            //这里是微信绑定操作
            String cookie = request.getHeader("Cookie");
            Integer id = getIdByCookie(cookie);

            if(bcraPersonalInfo == null ||id!=null) { //数据库不存在微信信息
                //第三步 拿着openid  和  access_token请求微信地址，得到扫描人信息
                String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                        "?access_token=%s" +
                        "&openid=%s";
                String userInfoUrl = String.format(baseUserInfoUrl, access_token, openid);
                //得到最终扫码人的信息
                String resultInfo = HttpClientUtils.get(userInfoUrl);
                System.out.println("resultInfo:"+resultInfo);

                JSONObject resultUserInfoJson = JSONObject.parseObject(resultInfo);
                //解析用户信息
                //用户昵称
                String nickname = resultUserInfoJson.getString("nickname");
                //用户头像
                //String headimgurl = resultUserInfoJson.getString("headimgurl");

                if(id!=null){
                    String redirectUrl="http://localhost:3000/#/systemManagement/personalInformation/"+id;
                    if (bcraPersonalInfo != null){
                        redirectUrl=redirectUrl+"?error=error";
                        response.sendRedirect(redirectUrl);throw new BaseException(ResponseEnum.WEIXIN_HAS_BIND_ERROR);//说明微信已被绑定。
                    }else {
                        bcraPersonalInfoService.bindWechat(id, openid, nickname);
                        response.sendRedirect(redirectUrl);
                        return;
                    }
                }

                //获取扫描人信息添加数据库
                bcraPersonalInfo = new BcraPersonalInfo();
                //过滤表情 ，万一有图案
                bcraPersonalInfo.setNickname(EmojiFilter.filterEmoji(nickname));
                //创建用户时候需要绑定微信号
                bcraPersonalInfo.setWechat(EmojiFilter.filterEmoji(nickname));
                bcraPersonalInfo.setOpenId(openid);
                bcraPersonalInfoService.registerUser(bcraPersonalInfo);
            }
            //返回name和token字符串
            Map<String,Object> map = new HashMap<>();

            String token ="";

            //判断userInfo是否有手机号，如果手机号为空，返回openid
            //如果手机号不为空，返回openid值是空字符串
            //前端判断：如果openid不为空，绑定手机号，如果openid为空，不需要绑定手机号
            if(StringUtils.isEmpty(bcraPersonalInfo.getPhone())) {
                map.put("openid", bcraPersonalInfo.getOpenId());
                //使用jwt生成token字符串,把open_id当作手机号使用
                token = JwtHelper.createToken(bcraPersonalInfo.getId(), bcraPersonalInfo.getOpenId());
            } else {
                map.put("openid", "");
                token = JwtHelper.createToken(bcraPersonalInfo.getId(), bcraPersonalInfo.getPhone());
            }

            map.put("token", token);
            map.put("information",bcraPersonalInfo);

            String redirectUrl="http://localhost:3000/#/login?id="+bcraPersonalInfo.getId()+"&token="+token;

            response.sendRedirect(redirectUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Integer getIdByCookie(String cookie){
        String[] strings = cookie.split("; ");

        for (String string : strings) {
            if(string.contains("id=")){
                if (string.length()==3){
                    return null;
                }
                return Integer.valueOf(string.substring(3));
            }
        }
        return null;
    }
}
